package kalp.entities;

import java.io.IOException;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class EntitiesService {

	@PersistenceContext
	private EntityManager em;
	private ObjectMapper om = new ObjectMapper();

	public EntitiesService() {
	}

	public EntitiesService(EntityManager em) {
		this.em = em;
	}

	@Transactional
	public JsonNode getValue(String key) {
		Thing t = em.find(Thing.class, key);
		if (t != null) {
			byte[] bytes = t.getData();
			try {
				return om.readTree(bytes);
			} catch (JsonProcessingException e) {
				throw new CorruptedDataException();
			} catch (IOException e) {
				throw new CorruptedDataException();
			}
		}
		return null;
	}

	@Transactional
	public void setValue(String key, JsonNode value) {
		try {
			byte[] bytes = om.writeValueAsBytes(value);
			Thing t = new Thing();
			t.setKey(key);
			t.setData(bytes);
			em.merge(t);
		} catch (JsonGenerationException e) {
			throw new CorruptedDataException();
		} catch (JsonMappingException e) {
			throw new CorruptedDataException();
		} catch (IOException e) {
			throw new CorruptedDataException();
		}
	}

	@Transactional
	public <T> T get(String key, Class<T> type) {
		JsonNode json = getValue(key);
		if (json != null) {
			return om.convertValue(json, type);
		}
		return null;
	}

	@Transactional
	public void set(String key, Object o) {
		JsonNode json = om.convertValue(o, JsonNode.class);
		setValue(key, json);
	}
}
